﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Emgu.CV;
using Emgu.Util;
using System.Diagnostics;
using Emgu.CV.Structure;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Features2D;

namespace NIP.VisionSharp
{
    class Surf
    {
        private Capture cap;
        private SURFFeature[] features;
        private SURFDetector surfParam;
        private Rectangle objRect;


        public Surf()
        {

            surfParam = new SURFDetector(500, false);
            if (cap == null)
            {
                try
                {
                    cap = new Capture();
                    cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT, 720);
                    cap.SetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_WIDTH, 1280);

                }
                catch (Exception excpt)
                {

                    throw new Exception(excpt.Message);
                }
            }
        }

        public Image<Bgr, Byte> imageCapture()
        {
            if (cap == null)
            {
                try
                {
                    cap = new Capture();
                }
                catch
                {
                    Debug.WriteLine("Error in capture");
                    throw;
                }
            }
            else
            {
                try
                {
                    Image<Bgr, Byte> frame;
                    frame = cap.QueryFrame();
                    return frame;
                }
                catch
                {
                    Debug.WriteLine("Image not available");
                    throw;
                }
            }
            return null;
        }

        public void doDetection()
        {

            Image<Bgr, Byte> observedImage = imageCapture();
            Image<Gray, Byte> gray = observedImage.Convert<Gray, Byte>();
            // extract features from the observed image
            SURFFeature[] imageFeatures = gray.ExtractSURF(ref surfParam);

            //Create a SURF Tracker using k-d Tree
            SURFTracker tracker = new SURFTracker(features);
            //Comment out above and uncomment below if you wish to use spill-tree instead
            //SURFTracker tracker = new SURFTracker(modelFeatures, 50, .7, .1);

            SURFTracker.MatchedSURFFeature[] matchedFeatures = tracker.MatchFeature(imageFeatures, 2, 20);
            matchedFeatures = SURFTracker.VoteForUniqueness(matchedFeatures, 0.8);
            matchedFeatures = SURFTracker.VoteForSizeAndOrientation(matchedFeatures, 1.5, 20);
            HomographyMatrix homography = SURFTracker.GetHomographyMatrixFromMatchedFeatures(matchedFeatures);

           

            #region draw the project region on the image
            if (homography != null)
            {  //draw a rectangle along the projected model
                PointF[] pts = new PointF[] { 
               new PointF(objRect.Left, objRect.Bottom),
               new PointF(objRect.Right, objRect.Bottom),
               new PointF(objRect.Right, objRect.Top),
               new PointF(objRect.Left, objRect.Top)};
               homography.ProjectPoints(pts);

               observedImage.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Green) , 5);
            }
            #endregion
        }

        public void captureFeatures()
        {
            Image<Bgr, Byte> modelImage = imageCapture();
            objRect = modelImage.ROI;
            Image<Gray, Byte> gray = modelImage.Convert<Gray, Byte>();
            //extract features from the object image
           features = gray.ExtractSURF(ref surfParam);
  

        }
    }
}